package cameracontrol;

import java.util.List;

import event.*;
import gui.CameraPanel;
import se.lth.cs.realtime.JThread;
import se.lth.cs.realtime.RTInterrupted;
import se.lth.cs.realtime.event.RTEvent;

/**
 * MotionController is a thread which notify CameraController what speed they
 * should request pictures at. MotionController receives messages through a
 * mailbox, these messages contains information whether a motion occurred or it
 * stopped.
 */
public class MotionController extends JThread {
	private List<CameraController> list;
	private CameraPanel view;
	private boolean autoMode=true;
	private boolean movieMode;
	private boolean idleMode;
	private boolean run = true;

	/**
	 * Constructs the class
	 * 
	 * @param list
	 *            - the list contains all CameraController which should be
	 *            updated
	 */
	public MotionController(List<CameraController> list, CameraPanel cameraPanel) {
		this.view = cameraPanel;
		this.list = list;
		cameraPanel.setMotion(false,"");
	}

	/**
	 * Run whenever the thread is started.
	 */
	@Override
	public void run() {
		while (run) {
			RTEvent rtevent = mailbox.doFetch();
			MotionEvent event = null;
			
			if(rtevent instanceof MotionEvent) {
				event = (MotionEvent) rtevent;
				
			} else if (rtevent instanceof KillEvent) {
				continue;
			}			
			wake();
			if (autoMode) {
				if (event.getMotion()) {					
					setMotionOn(event.getAdress() + ": ");
				} else {
					setMotionOff(false,"");
				}
			}else if(movieMode){
				if (event.getMotion()) {
					setMotionOn("User: ");
				}
			}else if(idleMode){
				if (!event.getMotion()) {
					setMotionOff(true,"");
				}
			}			
		}
	}

	private synchronized void wake() {
		notifyAll();
	}

	private synchronized void setMotionOn(String adress) {
		for (CameraController cc : list) {
			cc.setPeriod(40);
			cc.wake();
		}
		view.setMotion(true, adress);
	}


	public void kill() {
		this.run = false;
		this.wake();
		mailbox.doPost(new KillEvent());
		try {
			this.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public synchronized RTEvent putEvent(RTEvent r) {
		notifyAll();
		return super.putEvent(r);
	}

	private synchronized void setMotionOff(boolean forced, String adress) {
		long time = System.currentTimeMillis();
		long sleeped = 0;
		try {
			if (!forced)
				wait(10000);
			sleeped = System.currentTimeMillis() - time;
		} catch (InterruptedException e) {
			e.printStackTrace();
			return;
		}
		if (sleeped >= 10000 || forced) {			
			for (CameraController cc : list){				
				cc.setPeriod(5000);
			}				
			view.setMotion(false, adress);
		}
	}

	public synchronized void setMovieMode() {
		movieMode=true;
		autoMode=false;
		idleMode=false;
	}

	public synchronized void setIdleMode() {
		idleMode=true;
		movieMode=false;
		autoMode=false;
	}

	public synchronized void setAutoMode() {
		autoMode=true;
		movieMode=false;
		idleMode=false;
	}

}
